dedicated device-driver domain, or your master control domain
(domain 0), then you almost certainly want to say Y here.
-config XEN_NETDEV_GRANT_TX
- bool "Grant table substrate for net drivers tx path (DANGEROUS)"
- default n
- help
- This introduces the use of grant tables as a data exhange mechanism
- between the frontend and backend network drivers.
-
-config XEN_NETDEV_GRANT_RX
- bool "Grant table substrate for net drivers rx path (DANGEROUS)"
+config XEN_NETDEV_GRANT
+ bool "Grant table substrate for network drivers (DANGEROUS)"
default n
help
This introduces the use of grant tables as a data exhange mechanism
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
xen_start_info.console_evtchn, handle_input,
0, "xencons", inring());
if (err) {
- xprintk(KERN_ERR "XEN console request irq failed %i\n", err);
+ xprintk("XEN console request irq failed %i\n", err);
unbind_evtchn_from_irq(xen_start_info.console_evtchn);
return err;
}
#include <asm/io.h>
#include <asm/pgalloc.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
+
+#define GRANT_INVALID_REF (0xFFFF)
+
#endif
#define ASSERT(_p) ((void)0)
#define DPRINTK(_f, _a...) ((void)0)
#endif
+#define IPRINTK(fmt, args...) \
+ printk(KERN_INFO "xen_net: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+ printk(KERN_WARNING "xen_net: " fmt, ##args)
+
typedef struct netif_st {
/* Unique identifier for this interface. */
/* Physical parameters of the comms window. */
unsigned long tx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u16 tx_shmem_handle;
unsigned long tx_shmem_vaddr;
grant_ref_t tx_shmem_ref;
#endif
unsigned long rx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u16 rx_shmem_handle;
unsigned long rx_shmem_vaddr;
grant_ref_t rx_shmem_ref;
/* Private indexes into shared ring. */
NETIF_RING_IDX rx_req_cons;
NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */
#endif
NETIF_RING_IDX tx_req_cons;
return netif;
}
-static int map_frontend_page(netif_t *netif, unsigned long localaddr,
- unsigned long tx_ring_ref, unsigned long rx_ring_ref)
+static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
+ unsigned long tx_ring_ref,
+ unsigned long rx_ring_ref)
{
-#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ struct gnttab_map_grant_ref op;
+
+ /* Map: Use the Grant table reference */
+ op.host_addr = localaddr;
+ op.flags = GNTMAP_host_map;
+ op.ref = tx_ring_ref;
+ op.dom = netif->domid;
+
+ BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+ if (op.handle < 0) {
+ DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n");
+ return op.handle;
+ }
+
+ netif->tx_shmem_ref = tx_ring_ref;
+ netif->tx_shmem_handle = op.handle;
+ netif->tx_shmem_vaddr = localaddr;
+
+ /* Map: Use the Grant table reference */
+ op.host_addr = localaddr + PAGE_SIZE;
+ op.flags = GNTMAP_host_map;
+ op.ref = rx_ring_ref;
+ op.dom = netif->domid;
+
+ BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+ if (op.handle < 0) {
+ DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n");
+ return op.handle;
+ }
+
+ netif->rx_shmem_ref = rx_ring_ref;
+ netif->rx_shmem_handle = op.handle;
+ netif->rx_shmem_vaddr = localaddr + PAGE_SIZE;
+
+#else
pgprot_t prot = __pgprot(_KERNPG_TABLE);
int err;
-#endif
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
- {
- struct gnttab_map_grant_ref op;
-
- /* Map: Use the Grant table reference */
- op.host_addr = localaddr;
- op.flags = GNTMAP_host_map;
- op.ref = tx_ring_ref;
- op.dom = netif->domid;
-
- BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
- if (op.handle < 0) {
- DPRINTK(" Grant table operation failure !\n");
- return op.handle;
- }
-
- netif->tx_shmem_ref = tx_ring_ref;
- netif->tx_shmem_handle = op.handle;
- netif->tx_shmem_vaddr = localaddr;
- }
-#else
+
err = direct_remap_area_pages(&init_mm, localaddr,
tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
prot, netif->domid);
- if (err)
- return err;
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
- {
- struct gnttab_map_grant_ref op;
-
- /* Map: Use the Grant table reference */
- op.host_addr = localaddr + PAGE_SIZE;
- op.flags = GNTMAP_host_map;
- op.ref = rx_ring_ref;
- op.dom = netif->domid;
-
- BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
- if (op.handle < 0) {
- DPRINTK(" Grant table operation failure !\n");
- return op.handle;
- }
-
- netif->rx_shmem_ref = rx_ring_ref;
- netif->rx_shmem_handle = op.handle;
- netif->rx_shmem_vaddr = localaddr + PAGE_SIZE;
- }
-#else
- err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
+
+ err |= direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
prot, netif->domid);
+
if (err)
return err;
#endif
return 0;
}
-static void unmap_frontend_page(netif_t *netif)
+static void unmap_frontend_pages(netif_t *netif)
{
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
struct gnttab_unmap_grant_ref op;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
op.host_addr = netif->tx_shmem_vaddr;
op.handle = netif->tx_shmem_handle;
op.dev_bus_addr = 0;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
op.host_addr = netif->rx_shmem_vaddr;
op.handle = netif->rx_shmem_handle;
op.dev_bus_addr = 0;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
#endif
+
+ return;
}
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
if (vma == NULL)
return -ENOMEM;
- err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
- rx_ring_ref);
+ err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref,
+ rx_ring_ref);
if (err) {
vfree(vma->addr);
return err;
op.u.bind_interdomain.port2 = evtchn;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
- unmap_frontend_page(netif);
+ unmap_frontend_pages(netif);
vfree(vma->addr);
return err;
}
unregister_netdev(netif->dev);
if (netif->tx) {
- unmap_frontend_page(netif);
+ unmap_frontend_pages(netif);
vfree(netif->tx); /* Frees netif->rx as well. */
}
#include <asm-xen/balloon.h>
#include <asm-xen/xen-public/memory.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#include <asm-xen/xen-public/grant_table.h>
-#include <asm-xen/gnttab.h>
-#ifdef GRANT_DEBUG
-static void
-dump_packet(int tag, u32 addr, unsigned char *p)
-{
- int i;
-
- printk(KERN_ALERT "#### rx_action %c %08x ", tag & 0xff, addr);
- for (i = 0; i < 20; i++) {
- printk("%02x", p[i]);
- }
- printk("\n");
-}
-#endif
-#endif
static void netif_idx_release(u16 pending_idx);
static void netif_page_release(struct page *page);
static struct sk_buff_head rx_queue;
static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
static gnttab_donate_t grant_rx_op[MAX_PENDING_REQS];
#else
static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE];
static struct sk_buff_head tx_queue;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
static u16 grant_tx_ref[MAX_PENDING_REQS];
static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS];
static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS];
+
#else
static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
#endif
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF (0xFFFF)
-#endif
-
static struct list_head net_schedule_list;
static spinlock_t net_schedule_list_lock;
return mfn;
}
-#ifndef CONFIG_XEN_NETDEV_GRANT_RX
+#ifndef CONFIG_XEN_NETDEV_GRANT
static void free_mfn(unsigned long mfn)
{
unsigned long flags;
dev_kfree_skb(skb);
skb = nskb;
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
#ifdef DEBUG_GRANT
printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x gr=%04x\n",
netif->rx->req_prod,
static void net_rx_action(unsigned long unused)
{
- netif_t *netif;
+ netif_t *netif = NULL;
s8 status;
u16 size, id, evtchn;
multicall_entry_t *mcl;
mmu_update_t *mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_donate_t *gop;
#else
struct mmuext_op *mmuext;
mcl = rx_mcl;
mmu = rx_mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gop = grant_rx_op;
#else
mmuext = rx_mmuext;
if ( (new_mfn = alloc_mfn()) == 0 )
{
if ( net_ratelimit() )
- printk(KERN_WARNING "Memory squeeze in netback driver.\n");
+ WPRINTK("Memory squeeze in netback driver.\n");
mod_timer(&net_timer, jiffies + HZ);
skb_queue_head(&rx_queue, skb);
break;
pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gop->mfn = old_mfn;
gop->domid = netif->domid;
gop->handle = netif->rx->ring[
mcl->args[3] = DOMID_SELF;
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
#else
mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
BUG();
mcl = rx_mcl;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- BUG_ON(HYPERVISOR_grant_table_op(
- GNTTABOP_donate, grant_rx_op, gop - grant_rx_op));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ if(HYPERVISOR_grant_table_op(GNTTABOP_donate, grant_rx_op,
+ gop - grant_rx_op)) {
+ /*
+ ** The other side has given us a bad grant ref, or has no headroom,
+ ** or has gone away. Unfortunately the current grant table code
+ ** doesn't inform us which is the case, so not much we can do.
+ */
+ DPRINTK("net_rx: donate to DOM%u failed; dropping (up to) %d "
+ "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op);
+ }
gop = grant_rx_op;
#else
mmuext = rx_mmuext;
/* Rederive the machine addresses. */
new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
#else
old_mfn = mmuext[0].mfn;
/* Check the reassignment error code. */
status = NETIF_RSP_OKAY;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- BUG_ON(gop->status != 0); /* XXX */
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ if(gop->status != 0) {
+ DPRINTK("Bad status %d from grant donate to DOM%u\n",
+ gop->status, netif->domid);
+ /* XXX SMH: should free 'old_mfn' here */
+ status = NETIF_RSP_ERROR;
+ }
#else
if ( unlikely(mcl[1].result != 0) )
{
netif_put(netif);
dev_kfree_skb(skb);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mcl++;
gop++;
#else
notify_via_evtchn(evtchn);
}
+ out:
/* More work to do? */
if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) )
tasklet_schedule(&net_rx_tasklet);
inline static void net_tx_action_dealloc(void)
{
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_unmap_grant_ref_t *gop;
#else
multicall_entry_t *mcl;
dc = dealloc_cons;
dp = dealloc_prod;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
/*
* Free up any grants we have finished using
*/
#endif
while ( dealloc_cons != dp )
{
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
/* The update_va_mapping() must not fail. */
BUG_ON(mcl[0].result != 0);
#endif
netif_put(netif);
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
mcl++;
#endif
}
netif_tx_request_t txreq;
u16 pending_idx;
NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_map_grant_ref_t *mop;
#else
multicall_entry_t *mcl;
if ( dealloc_cons != dealloc_prod )
net_tx_action_dealloc();
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop = tx_map_ops;
#else
mcl = tx_mcl;
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop->host_addr = MMAP_VADDR(pending_idx);
mop->dom = netif->domid;
mop->ref = txreq.addr >> PAGE_SHIFT;
pending_cons++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) )
break;
#else
#endif
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if ( mop == tx_map_ops )
return;
memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
/* Check the remap error code. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
/*
XXX SMH: error returns from grant operations are pretty poorly
specified/thought out, but the below at least conforms with
netif_rx(skb);
netif->dev->last_rx = jiffies;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop++;
#else
mcl++;
!(xen_start_info.flags & SIF_INITDOMAIN) )
return 0;
- printk("Initialising Xen netif backend\n");
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- printk("#### netback tx using grant tables\n");
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- printk("#### netback rx using grant tables\n");
+ IPRINTK("Initialising Xen netif backend.\n");
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ IPRINTK("Using grant tables.\n");
#endif
/* We can increase reservation by this much in net_rx_action(). */
#include <asm/page.h>
#include <asm/uaccess.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
+
+static grant_ref_t gref_tx_head;
+static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
+
+static grant_ref_t gref_rx_head;
+static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
+
+#define GRANT_INVALID_REF (0xFFFF)
+
#ifdef GRANT_DEBUG
static void
dump_packet(int tag, void *addr, u32 ap)
}
printk("\n");
}
+
+#define GDPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
+#else
+#define dump_packet(x,y,z) ((void)0)
+#define GDPRINTK(_f, _a...) ((void)0)
#endif
+
#endif
+
+
#ifndef __GFP_NOWARN
#define __GFP_NOWARN 0
#endif
#define TX_TEST_IDX req_cons /* conservative: not seen all our requests? */
#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-static grant_ref_t gref_tx_head;
-static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-static grant_ref_t gref_rx_head;
-static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF (0xFFFF)
-#endif
#define NETIF_STATE_DISCONNECTED 0
#define NETIF_STATE_CONNECTED 1
+
static unsigned int netif_state = NETIF_STATE_DISCONNECTED;
static void network_tx_buf_gc(struct net_device *dev);
for (i = np->tx_resp_cons; i != prod; i++) {
id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
skb = np->tx_skbs[id];
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) {
/* other domain is still using this grant - shouldn't happen
but if it does, we'll try to reclaim the grant later */
mb();
} while (prod != np->tx->resp_prod);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
out:
#endif
int i, batch_target;
NETIF_RING_IDX req_prod = np->rx->req_prod;
struct xen_memory_reservation reservation;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ grant_ref_t ref;
#endif
if (unlikely(np->backend_state != BEST_CONNECTED))
np->rx_skbs[id] = skb;
np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
ref = gnttab_claim_grant_reference(&gref_rx_head);
- if (unlikely(ref < 0)) {
+ if (unlikely((signed short)ref < 0)) {
printk(KERN_ALERT "#### netfront can't claim rx reference\n");
BUG();
}
struct net_private *np = netdev_priv(dev);
netif_tx_request_t *tx;
NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- unsigned int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ grant_ref_t ref;
unsigned long mfn;
#endif
tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
tx->id = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
ref = gnttab_claim_grant_reference(&gref_tx_head);
- if (unlikely(ref < 0)) {
+ if (unlikely((signed short)ref < 0)) {
printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
BUG();
}
network_tx_buf_gc(dev);
spin_unlock_irqrestore(&np->tx_lock, flags);
- if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN))
+ if((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN))
netif_rx_schedule(dev);
return IRQ_HANDLED;
int work_done, budget, more_to_do = 1;
struct sk_buff_head rxq;
unsigned long flags;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
unsigned long mfn;
grant_ref_t ref;
#endif
continue;
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- ref = grant_rx_ref[rx->id];
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ ref = grant_rx_ref[rx->id];
+
+ if(ref == GRANT_INVALID_REF) {
+ printk(KERN_WARNING "Bad rx grant reference %d from dom %d.\n",
+ ref, np->backend_id);
+ np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
+ wmb();
+ np->rx->req_prod++;
+ work_done--;
+ continue;
+ }
+
grant_rx_ref[rx->id] = GRANT_INVALID_REF;
mfn = gnttab_end_foreign_transfer_ref(ref);
gnttab_release_grant_reference(&gref_rx_head, ref);
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
/* NB. We handle skb overflow later. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
skb->data = skb->head + rx->addr;
#else
skb->data = skb->head + (rx->addr & ~PAGE_MASK);
np->stats.rx_bytes += rx->status;
/* Remap the page. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mmu->ptr = mfn << PAGE_SHIFT | MMU_MACHPHYS_UPDATE;
#else
mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
#endif
mmu->val = __pa(skb->head) >> PAGE_SHIFT;
mmu++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
pfn_pte_ma(mfn, PAGE_KERNEL), 0);
#else
#endif
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn;
+ GDPRINTK("#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n",
+ skb->data, mfn, ref);
#else
phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] =
rx->addr >> PAGE_SHIFT;
-#endif
+#endif
+
-#ifdef GRANT_DEBUG
- printk(KERN_ALERT "#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n",
- skb->data, mfn, ref);
-#endif
__skb_queue_tail(&rxq, skb);
}
+
/* Some pages are no longer absent... */
balloon_update_driver_allowance(-work_done);
}
while ((skb = __skb_dequeue(&rxq)) != NULL) {
-#ifdef GRANT_DEBUG
- printk(KERN_ALERT "#### rx_poll dequeue vdata=%p mfn=%lu\n",
- skb->data, virt_to_mfn(skb->data));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ GDPRINTK("#### rx_poll dequeue vdata=%p mfn=%lu\n",
+ skb->data, virt_to_mfn(skb->data));
dump_packet('d', skb->data, (unsigned long)skb->data);
#endif
/*
return &np->stats;
}
-
static void network_connect(struct net_device *dev)
{
struct net_private *np;
tx = &np->tx->ring[requeue_idx++].req;
tx->id = i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- tx->addr = 0; /*(ref << PAGE_SHIFT) |*/
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ gnttab_grant_foreign_access_ref(grant_tx_ref[i], np->backend_id,
+ virt_to_mfn(np->tx_skbs[i]->data),
+ GNTMAP_readonly);
+ tx->addr = grant_tx_ref[i] << PAGE_SHIFT;
#else
tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
#endif
np->tx->req_prod = requeue_idx;
/* Rebuild the RX buffer freelist and the RX ring itself. */
- for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++)
- if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET)
- np->rx->ring[requeue_idx++].req.id = i;
+ for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) {
+ if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ /* Reinstate the grant ref so backend can 'donate' mfn to us. */
+ gnttab_grant_foreign_transfer_ref(grant_rx_ref[i], np->backend_id,
+ virt_to_mfn(np->rx_skbs[i]->head)
+ );
+ np->rx->ring[requeue_idx].req.gref = grant_rx_ref[i];
+#endif
+ np->rx->ring[requeue_idx].req.id = i;
+ requeue_idx++;
+ }
+ }
+
wmb();
np->rx->req_prod = requeue_idx;
/* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
for (i = 0; i <= NETIF_TX_RING_SIZE; i++) {
np->tx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_tx_ref[i] = GRANT_INVALID_REF;
#endif
}
+
for (i = 0; i <= NETIF_RX_RING_SIZE; i++) {
np->rx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_rx_ref[i] = GRANT_INVALID_REF;
#endif
}
evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
int err;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
memset(info->rx, 0, PAGE_SIZE);
info->backend_state = BEST_DISCONNECTED;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
err = gnttab_grant_foreign_access(info->backend_id,
virt_to_mfn(info->tx), 0);
if (err < 0) {
goto out;
}
info->tx_ring_ref = err;
-#else
- info->tx_ring_ref = virt_to_mfn(info->tx);
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
err = gnttab_grant_foreign_access(info->backend_id,
virt_to_mfn(info->rx), 0);
if (err < 0) {
goto out;
}
info->rx_ring_ref = err;
+
#else
+ info->tx_ring_ref = virt_to_mfn(info->tx);
info->rx_ring_ref = virt_to_mfn(info->rx);
#endif
if (info->rx)
free_page((unsigned long)info->rx);
info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (info->tx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->tx_ring_ref, 0);
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
if (info->rx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
+
return err;
}
if (info->rx)
free_page((unsigned long)info->rx);
info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (info->tx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->tx_ring_ref, 0);
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
if (info->rx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
+
unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
info->evtchn = 0;
}
int err;
err = talk_to_backend(dev, np);
+
return err;
}
if (xen_start_info.flags & SIF_INITDOMAIN)
return 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- /* A grant for every ring slot */
+ if ((err = xennet_proc_init()) != 0)
+ return err;
+
+ IPRINTK("Initialising virtual ethernet driver.\n");
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ IPRINTK("Using grant tables.\n");
+
+ /* A grant for every tx ring slot */
if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
&gref_tx_head) < 0) {
printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
return 1;
}
- printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n");
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- /* A grant for every ring slot */
+ /* A grant for every rx ring slot */
if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
&gref_rx_head) < 0) {
printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
return 1;
}
- printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n");
#endif
- if ((err = xennet_proc_init()) != 0)
- return err;
-
- IPRINTK("Initialising virtual ethernet driver.\n");
(void)register_inetaddr_notifier(¬ifier_inetdev);
static void netif_exit(void)
{
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_free_grant_references(gref_tx_head);
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
gnttab_free_grant_references(gref_rx_head);
#endif
}
xen_start_info.store_evtchn, wake_waiting,
0, "xenbus", &xb_waitq);
if (err) {
- printk(KERN_ERR "XENBUS request irq failed %i\n", err);
+ xprintk("XENBUS request irq failed %i\n", err);
unbind_evtchn_from_irq(xen_start_info.store_evtchn);
return err;
}
}
if (!xs_watch(xs, "/console", "console")) {
- dolog(LOG_ERR, "xenstore watch on /console failes.");
+ dolog(LOG_ERR, "xenstore watch on /console fails.");
goto out_close_data;
}
struct domain *d = current->domain;
struct vcpu *v;
+ if(reason == SHUTDOWN_crash)
+ printk("Domain %d crash detected.\n", d->domain_id);
+
if ( d->domain_id == 0 )
{
extern void machine_restart(char *);
e->tot_pages, e->max_pages);
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) {
printk("gnttab_donate: target domain is dying\n");
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) {
- printk("gnttab_donate: gnttab_prepare_for_transfer fails\n");
+ printk("gnttab_donate: gnttab_prepare_for_transfer fails.\n");
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
#else
e->tot_pages, e->max_pages, gop->handle, e->d_flags);
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ /* XXX SMH: better error return here would be useful */
+ gop->status = result = GNTST_general_error;
break;
}
#endif
lgt = ld->grant_table;
#if GRANT_DEBUG_VERBOSE
- if ( ld->domain_ id != 0 ) {
+ if ( ld->domain_id != 0 ) {
DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
rd->domain_id, ld->domain_id, frame, readonly);
}
typedef struct {
u16 id; /* Echoed in response message. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_ref_t gref; /* 2: Reference to incoming granted frame */
#endif
} netif_rx_request_t;
typedef struct {
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u32 addr; /* 0: Offset in page of start of received packet */
#else
unsigned long addr; /* Machine address of packet. */